# -*- coding: utf-8 -*-
# @Author: Jerry
# @Date:   2022-02-21 14:27:44
# @Last Modified by:   Jerry
# @Last Modified time: 2022-02-21 17:20:42

# http://www.woshicver.com/
# 这里，我们通过拖动鼠标来绘制矩形或圆形(取决于我们选择的模式) ，
# 就像我们在 Paint 应用程序中所做的那样

# 所以我们的鼠标回调函数有两部分，
# 一部分用于绘制矩形，
# 另一部分用于绘制圆形。
# 这个具体的例子对于创建和理解一些交互式应用程序非常有帮助，比如目标跟踪，图像分割地图等等。

import numpy as np
import cv2 as cv

# **********
drawing = False # 如果按下鼠标，则为真
mode = True # 如果为真，绘制矩形。按 m 键可以切换到曲线
ix,iy = -1,-1

# **********
# 鼠标回调函数， 参数列表固定
def draw_circle(event,x,y,flags,param):
	global ix,iy,drawing,mode
	if event == cv.EVENT_LBUTTONDOWN:
		drawing = True
		ix,iy = x,y
	elif event == cv.EVENT_MOUSEMOVE: # 鼠标移动时画图，显示中间画图过程，随时变化
		if drawing == True:
			if mode == True:
				cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
			else:
				cv.circle(img,(x,y),5,(0,0,255),-1)
	elif event == cv.EVENT_LBUTTONUP: # 鼠标释放时画图，最终显示的图
		drawing = False
		if mode == True:
			cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
		else:
			cv.circle(img,(x,y),5,(0,0,255),-1)

# **********
# 创建一个黑色的图像，一个窗口，并绑定到窗口的功能
img = np.zeros((512,512,3),np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle) # 调用鼠标回调函数的方式
while True:
	cv.imshow('image',img)
	if cv.waitKey(20) & 0xFF == 27: #按键 cmd + q
		break

# **********
cv.destroyAllWindows()

# **********
# bug: 当鼠标第二次开始想<第一个点坐标快速移动时，将形成一个锯齿形的边框，而不是平滑的矩形
# 原因: 鼠标快速移动过程中，电脑有多次侦测到move的终点，造成每次都会画出来一个角，从而形成锯齿形

